package com.gege;

import java.io.FileNotFoundException;
import java.io.InputStream;

/**
 * 自定义类加载器
 *
 * 2.（必做）自定义一个 Classloader，加载一个 Hello.xlass 文件，执行 hello 方法，
 * 此文件内容是一个 Hello.class 文件所有字节（x=255-x）处理后的文件。文件群里提供。
 *
 * @author gechenpeng
 * @date 2021-03-17
 */
public class CustomClassLoader extends ClassLoader {

    private static final String SUFFIX = ".xlass";

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        // 定义一个字节数组
        byte[] bytes;

        // 根据类全路径名解析文件路径
        String filePath = name.replace('.', '/');

        // 读取加密处理过的字节码文件
        try (InputStream inputStream = getClass().getClassLoader()
                .getResourceAsStream(filePath + SUFFIX)) {
            if (null == inputStream) {
                throw new FileNotFoundException();
            }

            bytes = new byte[inputStream.available()];
            // 读取文件流到字节数组
            inputStream.read(bytes);
        } catch (Exception e) {
            throw new ClassNotFoundException(e.getMessage(), e);
        }

        // 解密字节数组
        decodeBytes(bytes);

        // 将字节数组转换为字节码对象
        return defineClass(name, bytes, 0, bytes.length);
    }

    /**
     * 解密字节数组
     *
     * @param bytes
     */
    private void decodeBytes(byte[] bytes) {
        // 将字节数组中的每个字节按 255 - x 置换
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) (255 - bytes[i]);
        }
    }
}
